package com.gs.pojo.utils;

import com.google.common.collect.Lists;
import com.gs.common.tool.consts.DbDriverConst;
import com.gs.common.tool.consts.FrameConst;
import com.gs.common.tool.pojo.ColumnInfo;
import com.gs.common.tool.utils.LombokUtil;
import com.gs.common.tool.utils.PoJoUtil;
import com.gs.common.tool.utils.StringUtil;
import com.gs.common.tool.utils.UuidUtil;

import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * 生成java 类
 * @author: guos
 * @date: 2024/12/04 15:00
 **/
public class GenerateJavaUtil {


    /**
     * 生成实体类
     * @param tableStructStr    表结构
     * @date 2024/12/04 15:01
     **/
    public static String generatePojo(String tableStructStr) {
        if (StringUtil.isEmpty(tableStructStr)) {
            return "";
        }
        SimpleDateFormat sdf = new SimpleDateFormat("yyyy/MM/dd HH:mm");
        Date date = new Date();
        List<String> columnStrList = Lists.newArrayList(tableStructStr.split("\r\n"));
        //框架信息
        String frameStr = columnStrList.get(0);
        String frame = frameStr.split("\t")[1];
        //表信息
        String tableStr = columnStrList.get(1);
        String[] tableInfos = tableStr.split("\t");
        String tableName = tableInfos[0];
        String dbType = tableInfos[1];
        String tableComment = tableInfos[2];
        columnStrList.remove(frameStr);
        columnStrList.remove(tableStr);
        StringBuilder beanStr = new StringBuilder();
        beanStr.append(importFrameClz(frame));
        //第三方类导入
        List<String> lombokList = LombokUtil.addAnnotationFullName(false);
        String lombokStr = lombokList.stream().map(d -> String.format("import %s;", d)).collect(Collectors.joining("\n"));
        beanStr.append(lombokStr);
        beanStr.append("import java.io.Serializable;\n");
        if (tableStructStr.contains("decimal") || tableStructStr.contains("numeric")) {
            beanStr.append("import java.math.BigDecimal;\n");
        }
        if (tableStructStr.contains("date") || tableStructStr.contains("datetime") || tableStructStr.contains("timestamp")) {
            beanStr.append("import java.util.Date;\n");
        }
        if (tableStructStr.contains("time")) {
            beanStr.append("import java.sql.Time;\n");
        }
        beanStr.append("\n\n\n\n").append(String.format("/**\n" + " * %s\n" + " * @author %s\n" + " * @date %s\n" + " */\n", tableComment, "guos", sdf.format(date)));
        //获取注解简称名称
        String lombokShortName = LombokUtil.getAnnotationShortName(LombokUtil.addAnnotationShortName(false));
        beanStr.append(String.format("%s@%s\n", lombokShortName, FrameConst.TK.equals(frame) ? String.format("Table(name = \"%s\")", tableName) : String.format("TableName(\"%s\")", tableName)));
        beanStr.append(String.format("public class %s implements Serializable {", getBeanName(tableName, dbType)));
        beanStr.append(String.format("\n\n\t/**\n\t* serialVersionUID\n\t*/\n\tprivate static long serialVersionUID = %sL;", UuidUtil.generateNum(16)));
        List<ColumnInfo> columnList = columnStrList.stream().map(cr -> {
            ColumnInfo columnInfo = new ColumnInfo();
            String[] cols = cr.split("\t");
            columnInfo.setColumnName(cols[0]).setColumnComment(cols[2]).setColumnType(cols[1]).setPK("1".equals(cols[3]));
            return columnInfo;
        }).collect(Collectors.toList());
        //如果有多个主键，只给第一个加主键注解，其它加正常属性注解
        String pkCol = columnList.stream().filter(ColumnInfo::isPK).map(ColumnInfo::getColumnName).findFirst().orElse(null);
        columnList.stream().map(d -> d.getColumnName().equals(pkCol) ? d.setPK(true) : d.setPK(false)).forEach(c -> beanStr.append(PoJoUtil.outputFields(frame, c)));
        beanStr.append("\n}\n");
        return beanStr.toString();
    }


    /**
     * 获取实体类名
     * @param tableName    表名
     * @param dbType 数据库类型
     * @date 2024/12/05 10:24
     **/
    private static String getBeanName(String tableName, String dbType) {
        //表名包含模式名，需求去掉(tsyj.user)
        String trueTableName = tableName.contains(".") ? tableName.split("\\.")[1] : tableName;
        String beanName;
        if (DbDriverConst.POSTGRESQL.equals(dbType)) {
            beanName = PoJoUtil.lineToHump(String.format("holo_%s", trueTableName));
        } else {
            beanName = PoJoUtil.lineToHump(trueTableName);
        }
        return PoJoUtil.firstToUpper(beanName);
    }


    /**
     * 根据框架类型导入类
     * @param frame    框架类型
     * @date 2024/12/05 15:00
     **/
    private static String importFrameClz(String frame) {
        if (FrameConst.TK.equals(frame)) {
            return "import javax.persistence.Column;\n" + "import javax.persistence.Id;\n" + "import javax.persistence.Table;\n";
        } else {
            return "import com.baomidou.mybatisplus.annotation.*;\nimport com.fasterxml.jackson.databind.annotation.JsonSerialize;\nimport com.fasterxml.jackson.databind.ser.std.ToStringSerializer;\n";
        }
    }
}
